package cn.hdr.train.concurrent;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 生产者消费者模型
 * @author: hdr
 * @date: 2020-12-12 17:15
 */
public class ProduceComsumerTest {

    private final static int MAX_STORE = 100;

    private int store = 0;

    private ReentrantLock lock = new ReentrantLock();

    private Condition notEmpty = lock.newCondition();

    private Condition notFull = lock.newCondition();


    public void send(int num){
        if(num <= 0){
            return;
        }
        try {
            lock.lock();

            while ((store + num) > MAX_STORE){
                System.out.println("仓库容量已满：" + (store + num));
                notFull.await();
            }
            store += num;
            notEmpty.signalAll();

            System.out.println("生产： " + num + "个,库存数量： " + store);
        }catch (InterruptedException ie){
            ie.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void receivce(int num){
        if(num <= 0){
            return;
        }
        try {
            lock.lock();

            while (store < num){
                System.out.println("仓库库存不足：" + (store - num));
                notEmpty.await();
            }
            store -= num;
            notFull.signalAll();

            System.out.println("消费： " + num + "个,库存数量： " + store);
        }catch (InterruptedException ie){
            ie.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public int getStore() {
        return store;
    }

    public static void main(String[] args) {
        ProduceComsumerTest factory = new ProduceComsumerTest();
        long now = System.currentTimeMillis();
        final int time = 60 * 1000;
        //生产
        new Thread(()->{
            try {
                Random random = new Random();
                while (System.currentTimeMillis() - now < time){
                    factory.send(random.nextInt(9)+1);
                    Thread.sleep(random.nextInt(500) + 100);
                }
            }catch (InterruptedException ie){
                ie.printStackTrace();
            }
        }).start();


        //
        new Thread(()->{
            try {
                Random random = new Random();
                while (System.currentTimeMillis() - now < time){
                    factory.receivce(random.nextInt(9)+1);
                    Thread.sleep(random.nextInt(200) + 100);
                }
            }catch (InterruptedException ie){
                ie.printStackTrace();
            }
        }).start();
    }

}